package com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.deviceIn;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.util.CollectionUtils;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.flowable.dto.FlowFormDeviceInDetailDto;
import com.glsc.ngateway.common.api.flowable.dto.task.doTaskParam.AbstractFlowSearchParamDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.DeviceInTaskFormDto;
import com.glsc.ngateway.common.api.flowable.dto.task.formData.cmdb.domainDto.FlowFormDeviceInDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.platform.dto.user.UserLeadersDto;
import com.glsc.ngateway.common.base.converter.platform.FlowFormDeviceInConverter;
import com.glsc.ngateway.common.base.converter.platform.FlowFormDeviceInDetailConverter;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowPushOaLog;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormDeviceIn;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.cmdb.FlowFormDeviceInDetail;
import com.glsc.ngateway.common.base.domain.sqlserver.glsec.TAmEhrEmpEntity;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowEnum;
import com.glsc.ngateway.common.base.enums.itflow.ITFlowTaskParamEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.flow.cmdb.*;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.AbstractItFlowStrategy;
import com.glsc.ngateway.platform.service.itflow.flowstrategy.cmdb.deviceIn.taskPostHandler.IDeviceInTaskPostHandlerAudit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhengyr
 * @date 2023/8/2-15:22
 */
@Component
public class DeviceInFlowStrategy extends AbstractItFlowStrategy<FlowFormDeviceInDto, DeviceInTaskFormDto> {
    private Map<String, IDeviceInTaskPostHandlerAudit> taskPostHandlerMap;

    @Autowired
    FlowFormDeviceInRepo flowFormDeviceInRepo;
    @Autowired
    FlowFormCPUInDetailRepo cpuInDetailRepo;
    @Autowired
    FlowFormMemoryInDetailRepo memoryInDetailRepo;
    @Autowired
    FlowFormDiskInDetailRepo diskInDetailRepo;
    @Autowired
    FlowFormDeviceInDetailRepo deviceInDetailRepo;
    @Autowired
    private UserService userService;

    @Autowired
    public void setTaskPostHandlerMap(List<IDeviceInTaskPostHandlerAudit> taskPostHandlerList) {
        this.taskPostHandlerMap = taskPostHandlerList.stream()
                .collect(Collectors.toMap(IDeviceInTaskPostHandlerAudit::getTaskDefinitionKey, handler -> handler));
    }

    @Override
    protected Map getTaskPassMap() {
        return taskPostHandlerMap;
    }

    @Override
    protected Map getTaskRejectMap() {
        return taskPostHandlerMap;
    }

    @Override
    public ITFlowEnum getFlowEnum() {
        return ITFlowEnum.CMDB_DEVICE_IN;
    }

    @Override
    public List<String> pageProcessId(AbstractFlowSearchParamDto param, Pageable pageable) {
        return null;
    }

    @Override
    public DeviceInTaskFormDto saveOrUpdateForm(DeviceInTaskFormDto flowableForm) {
        if (StrUtil.isEmpty(flowableForm.getProcessId())) {
            throw PlatformException.error("没有流程processId,无法保存流程数据", false, false);
        }
        //保存流程主表单数据
        FlowFormDeviceIn oldData = flowFormDeviceInRepo.findByProcessId(flowableForm.getProcessId());
        if (Objects.nonNull(oldData)) {
            flowableForm.getFormMainData().setId(oldData.getId());
        }
        flowFormDeviceInRepo.save(Objects.requireNonNull(FlowFormDeviceInConverter.dto2Do(flowableForm.getFormMainData())));
        //保存新增的设备明细数据到流程表单子表。先删除已有processId的全部数据，再插入
        saveAllDetailList(flowableForm.getProcessId(), flowableForm);

        return flowableForm;
    }

    @Override
    public DeviceInTaskFormDto findFormByProcessId(String processId) {
        DeviceInTaskFormDto flowableForm = new DeviceInTaskFormDto();
        FlowFormDeviceIn formMainDataDo = flowFormDeviceInRepo.findByProcessId(processId);
        if (Objects.isNull(formMainDataDo)) {
            flowableForm.setFormMainData(new FlowFormDeviceInDto());
        } else {
            flowableForm.setFormMainData(FlowFormDeviceInConverter.do2Dto(formMainDataDo));
//            flowableForm.setCpuInDataList(cpuInDetailRepo.findAllByprocessId(processId));
//            flowableForm.setMemoryInDataList(memoryInDetailRepo.findAllByprocessId(processId));
//            flowableForm.setDiskInDataList(diskInDetailRepo.findAllByprocessId(processId));
            flowableForm.setDeviceInDataList(FlowFormDeviceInDetailConverter.do2Dto(deviceInDetailRepo.findAllByprocessId(processId)));
        }
        return flowableForm;
    }

    /**
     * 前端规格数据保存到流程子表
     *
     * @throws Exception
     */
    private void saveAllDetailList(String processId, DeviceInTaskFormDto flowableForm) {
        //先删除所有当前流程的子表数据
//        cpuInDetailRepo.deleteAll(cpuInDetailRepo.findAllByprocessId(processId));
//        memoryInDetailRepo.deleteAll(memoryInDetailRepo.findAllByprocessId(processId));
//        diskInDetailRepo.deleteAll(diskInDetailRepo.findAllByprocessId(processId));
        deviceInDetailRepo.deleteAll(deviceInDetailRepo.findAllByprocessId(processId));
//        List<FlowFormCPUInDetail> cpuInDataList = flowableForm.getCpuInDataList();
//        List<FlowFormMemoryInDetail> memoryInDataList = flowableForm.getMemoryInDataList();
//        List<FlowFormDiskInDetail> diskInDataList = flowableForm.getDiskInDataList();
        List<FlowFormDeviceInDetailDto> deviceInDataList = flowableForm.getDeviceInDataList();
        //再插入当前提交的数据
//        if(!CollectionUtils.isEmpty(cpuInDataList)){
//            cpuInDetailRepo.saveAll(cpuInDataList.stream().map(h -> {
//                h.setProcessId(flowableForm.getProcessId());
//                return h;
//            }).collect(Collectors.toList()));
//        }
//        if(!CollectionUtils.isEmpty(memoryInDataList)){
//            memoryInDetailRepo.saveAll(memoryInDataList.stream().map(h -> {
//                h.setProcessId(flowableForm.getProcessId());
//                return h;
//            }).collect(Collectors.toList()));
//        }
//        if(!CollectionUtils.isEmpty(diskInDataList)){
//            diskInDetailRepo.saveAll(diskInDataList.stream().map(h -> {
//                h.setProcessId(flowableForm.getProcessId());
//                return h;
//            }).collect(Collectors.toList()));
//        }
        if (!CollectionUtils.isEmpty(deviceInDataList)) {
            deviceInDetailRepo.saveAll(
                    deviceInDataList.stream()
                            .map(h -> {
                                FlowFormDeviceInDetail domain = FlowFormDeviceInDetailConverter.dto2Do(h);
                                domain.setProcessId(flowableForm.getProcessId());
                                return domain;
                            })
                            .collect(Collectors.toList())
            );
        }
    }


    @Resource
    private IFeignLdapService ehrService;

    /**
     * 流程节点，发起时动态指定节点处理人
     */
    @Override
    protected Map<String, List<String>> initDefaultTaskUserGroup(PlatformUserDto creator) throws PlatformException {
        AppEhrResponse staffRes = ehrService.getLdapEhrEmp(creator.getUsername(), null, false);
        TAmEhrEmpEntity staffEntity;
        if (Objects.isNull(staffRes) || staffRes.getStatus() != 0) {
            throw PlatformException.error(String.format("未找到员工%s信息", creator.getUsername()));
        } else {
            staffEntity = JSONObject.parseObject(JSONObject.toJSONString(staffRes.getData()), TAmEhrEmpEntity.class);
            //}
        }

        Map<String, List<String>> taskAssignee = new HashMap<>(16);
        UserLeadersDto userLeadersDto = userService.getDirectLeaderAndPrimaryDepartmentLeader(creator);
        if (CollectionUtils.isEmpty(userLeadersDto.getDirectLeaders())) {
            throw PlatformException.error("未找到直属上级", false, false);
        }
        //1、发起人
        taskAssignee.put(ITFlowTaskParamEnum.CMDB_DEVICE_IN_FLOW_BEGIN_TASK_ASSIGNMENTS.getName(), Arrays.asList(creator.getUsername()));
        //2.上级领导审批
        //taskAssignee.put(ITFlowTaskParamEnum.CMDB_DEVICE_IN_FLOW_LEADER_TASK_ASSIGNMENTS.getName(), userLeadersDto.getDirectLeaders());
        taskAssignee.put(ITFlowTaskParamEnum.CMDB_DEVICE_IN_FLOW_LEADER_TASK_ASSIGNMENTS.getName(), Arrays.asList(staffEntity.getReportto()));
        //3、发起人确认
        taskAssignee.put(ITFlowTaskParamEnum.CMDB_DEVICE_IN_FLOW_CREATOR_AUDIT_TASK_ASSIGNMENTS.getName(), Arrays.asList(creator.getUsername()));
        taskAssignee.put(ITFlowTaskParamEnum.CMDB_DEVICE_IN_FLOW_SYNC_OA_TASK_ASSIGNMENTS.getName(), Arrays.asList("admin"));
        return taskAssignee;
    }

    @Override
    public void endFromOaFlow(FlowPushOaLog log, String description) throws Exception {
        taskPostHandlerMap.get(log.getTaskKey()).endFromOaFlow(log, description);
    }
}
